import { AmmoLib } from '../AmmoLib.js'
import { WuLiWuTi } from './WuLiWuTi.js'

class WuLiRouTi extends WuLiWuTi {
	jianGe = 0.05 // 间隔
	wuTi = null
	wuTiLeiXing = '柔体'
	jinZhiPengZhuang = false // 连接物体间禁止碰撞
	yaLi = 120 // 压力
	xingZhuangLeiXing = null
	
	constructor(canShu, shiJie) {
		super()
		
		this.bianHao = canShu.bianHao
		this.mingZi = canShu.mingZi
		this.shiJie = shiJie
		this.wuTi = this.shengChengWuTi(canShu)
		this.shiJie.addSoftBody(this.wuTi, 1, -1)
	}
	
	
	// 生成物体
	shengChengWuTi(canShu) {
		let { weiZhi, xuanZhuan, zhiLiang, pengZhuangTi: { xingZhuang, chiCun, mian, xian, ti } } = canShu
		
		let softBody = null
		let softBodyHelpers = new AmmoLib.btSoftBodyHelpers();
		
		this.xingZhuangLeiXing = xingZhuang
		
		if (xingZhuang == '面') {
			let segmentsX = chiCun.widthSegments + 1
			let segmentsY = chiCun.heightSegments + 1

			const zuoShang = new AmmoLib.btVector3(...mian.zuoShang);
			const youShang = new AmmoLib.btVector3(...mian.youShang);
			const zuoXia = new AmmoLib.btVector3(...mian.zuoXia);
			const youXia = new AmmoLib.btVector3(...mian.youXia);

			softBody = softBodyHelpers.CreatePatch( this.shiJie.getWorldInfo(), zuoShang, youShang, zuoXia, youXia, segmentsX, segmentsY, 0, true );
			const sbConfig = softBody.get_m_cfg();
			sbConfig.set_viterations( 10 );
			sbConfig.set_piterations( 10 );
			AmmoLib.castObject( softBody, AmmoLib.btCollisionObject ).getCollisionShape().setMargin( this.jianGe * 3);
			
			if (xuanZhuan) {
				let btQ = new AmmoLib.btQuaternion()
				btQ.setValue(...xuanZhuan)
				// softBody.rotate(btQ)
				// AmmoLib.destroy(btQ)
			}
			
			AmmoLib.destroy(zuoShang)
			AmmoLib.destroy(youShang)
			AmmoLib.destroy(zuoXia)
			AmmoLib.destroy(youXia)
		}
		if (xingZhuang == '线') {
			let moWeiZhi = xian.moWeiZhi // 末尾位置
			let duanShu = xian.duanShu - 1 //  段数 + 1 = 端点数 = duanShu + 2；CreateRope内部duanShu会 + 2

			const qiDian = new AmmoLib.btVector3(...weiZhi);
			const zhongDian = new AmmoLib.btVector3(...moWeiZhi);
			softBody = softBodyHelpers.CreateRope( this.shiJie.getWorldInfo(), qiDian, zhongDian, duanShu, 0 );
			const sbConfig = softBody.get_m_cfg();
			sbConfig.set_viterations( 10 );
			sbConfig.set_piterations( 10 );
			AmmoLib.castObject( softBody, AmmoLib.btCollisionObject ).getCollisionShape().setMargin( this.jianGe * 3);
			
			this.jinZhiPengZhuang = true
			
			AmmoLib.destroy(qiDian)
			AmmoLib.destroy(zhongDian)
		}
		if (xingZhuang == '体') {
			let dingDian = ti.dingDian
			let suoYin = ti.suoYin

			softBody = softBodyHelpers.CreateFromTriMesh( this.shiJie.getWorldInfo(), dingDian, suoYin, suoYin.length / 3, true );
			const sbConfig = softBody.get_m_cfg();
			sbConfig.set_viterations( 40 );
			sbConfig.set_piterations( 40 );
			// Soft-soft and soft-rigid collisions
			sbConfig.set_collisions( 0x11 );
			// Friction
			sbConfig.set_kDF( 0.1 );
			// Damping
			sbConfig.set_kDP( 0.01 );
			// Pressure
			sbConfig.set_kPR( this.yaLi );
			// Stiffness
			softBody.get_m_materials().at( 0 ).set_m_kLST( 0.9 );
			softBody.get_m_materials().at( 0 ).set_m_kAST( 0.9 );
			
			AmmoLib.castObject( softBody, AmmoLib.btCollisionObject ).getCollisionShape().setMargin( this.jianGe );
		}
		
		softBody.setTotalMass( zhiLiang, false )
		// Disable deactivation
		softBody.setActivationState( 4 )

		return softBody
	}
	
	sheZhiWuTi(canShu) {
		const { shouLi, mao } = canShu
		const body = this.wuTi
		const btV3 = new AmmoLib.btVector3()
		let wuLiWuTiShuZu = WuLiWuTi.wuLiWuTiShuZu

		if (shouLi) {
			btV3.setValue(...shouLi)
			body.addForce( btV3 ); // 力需要持续添加
			// body.addAeroForceToNode(btV3, 2)
		}
		// 设置锚；设置锚点物体位置后，两物体距离太远会出问题
		if (mao) {
			for (let i = 0; i < mao.length; i++) {
				for (let j = 0; j < wuLiWuTiShuZu.length; j++) {
					let wuLiWuTi = wuLiWuTiShuZu[j]
					let maoDian = mao[i]
					if (wuLiWuTi.bianHao == maoDian.wuTiBianHao) {
						body.appendAnchor( maoDian.suoYin, wuLiWuTi.wuTi, this.jinZhiPengZhuang, 1 );
					}
				}
			}
		}

		AmmoLib.destroy(btV3)
	}
	
	// 更新物体
	gengXinWuTi() {
		let wuTi = this.wuTi
		let nodes = wuTi.get_m_nodes();
		let size = nodes.size()
		
		let dingDian = []
		let faXian = []
		let indexFloat = 0;
		let indexFloat1 = 0;
		for ( let i = 0; i < size; i++ ) {
			let node = nodes.at( i );
			let nodePos = node.get_m_x();
			dingDian[ indexFloat++ ] = nodePos.x() || 0;
			dingDian[ indexFloat++ ] = nodePos.y() || 0;
			dingDian[ indexFloat++ ] = nodePos.z() || 0;
			
			const nodeNormal = node.get_m_n();
			faXian[ indexFloat1++ ] = nodeNormal.x() || 0;
			faXian[ indexFloat1++ ] = nodeNormal.y() || 0;
			faXian[ indexFloat1++ ] = nodeNormal.z() || 0;
		}

		let jieGuo = {
			bianHao: this.bianHao,
			dingDian,
			faXian
		}
		
		return jieGuo
	}
	// 销毁物体
	xiaoHuiWuTi() {
		this.shiJie.removeSoftBody(this.wuTi)
		AmmoLib.destroy(this.wuTi)
	}
}

export {
	WuLiRouTi
}